
var scene, camera, light, renderer, raycaster, mesh, geometry, container;
var status, monitor;
var cameraParams = {};
var width, height;
var theta = 0, radius = 10, mouse, intersectedObj;
function initEnv() {
  width = window.innerWidth;
  height = window.innerHeight;

  container = document.getElementById("container");
  mouse = new THREE.Vector2(0, 0);
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
  light = new THREE.DirectionalLight(0xffffff, 1);
  raycaster = new THREE.Raycaster();
  renderer = new THREE.WebGLRenderer({ antialias: false });
  renderer.setSize(width, height);
  renderer.setClearColor(0xf0f0f0)
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.sortObjects = false;

  camera.position.x = 0;
  camera.position.y = 0;
  camera.position.z = 5;
  camera.lookAt({
    x: 0, y: 0, z: 0
  })
  light.position.set(1, 1, 1);
  scene.add(light);
  // scene.add(new THREE.AmbientLight(0x3e3e3e));
  container.appendChild(renderer.domElement);
}


function initStatus() {
  stats = new Stats();
  stats.domElement.style.position = "absolute";
  stats.domElement.style.top = "0px";
  container.appendChild(stats.domElement);
  container.appendChild(renderer.domElement);
}

function initMonitor() {
  cameraParams.up = {};
  cameraParams.x = 0;
  cameraParams.y = 0;
  cameraParams.z = 5;

  monitor = new DAT.GUI();
  monitor.add(cameraParams, "x", -2000, 2000).name("相机X的位置");
  monitor.add(cameraParams, "y", -2000, 2000).name("相机Y的位置");
  monitor.add(cameraParams, "z", -2000, 5000).name("相机Z的位置");
}

function initObj() {
  let num = 2000;
  geometry = new THREE.BoxGeometry(20, 20, 20);
  for (let i = 0; i < num; i++) {
    let obj = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({
      color: Math.random() * 0xffffff
    }))

    obj.position.x = Math.random() * 800 - 400;
    obj.position.y = Math.random() * 800 - 400;
    obj.position.z = Math.random() * 800 - 400;

    obj.rotation.x = Math.random() * 2 * Math.PI;
    obj.rotation.y = Math.random() * 2 * Math.PI;
    obj.rotation.z = Math.random() * 2 * Math.PI;

    obj.scale.x = Math.random() + 0.5;
    obj.scale.y = Math.random() + 0.5;
    obj.scale.z = Math.random() + 0.5;
    scene.add(obj);
  }
}

function initEventHandler() {
  document.body.addEventListener("mousemove", function (e) {
    e.preventDefault();
    mouse.x = e.clientX / width * 2 - 1;
    mouse.y = 1 - e.clientY / height * 2;
    // console.log("x,y", mouse.x, mouse.y);
  })
}

function init() {
  initEnv();
  initStatus();
  initMonitor();
  initObj();
  initEventHandler();
}

function updateMonitor() {
  // camera.position.x = cameraParams.x;
  // camera.position.y = cameraParams.y;
  // camera.position.z = cameraParams.z;
  camera.lookAt(scene.position);
  camera.updateProjectionMatrix();
}

function render() {
  var intersects = raycaster.intersectObjects(scene.children);
  raycaster.setFromCamera(mouse, camera);
  if (intersects.length) {
    if (intersectedObj != intersects[0].object) {
      if (intersectedObj) intersectedObj.material.emissive.setHex(intersectedObj.currentHex);
      intersectedObj = intersects[0].object;
      intersectedObj.currentHex = intersectedObj.material.emissive.getHex();
      intersectedObj.material.emissive.setHex(0xff0000);
    }
  } else {
    if (intersectedObj) intersectedObj.material.emissive.setHex(intersectedObj.currentHex);
    intersectedObj = null;
  }
  renderer.render(scene, camera);
}

function animate() {
  let position = camera.position;
  let { x, y, z } = position;

  theta += 0.2;
  camera.position.x = radius * Math.sin(THREE.Math.degToRad(theta));
  camera.position.y = radius * Math.sin(THREE.Math.degToRad(theta));
  camera.position.z = radius * Math.cos(THREE.Math.degToRad(theta));
  stats.update();
  updateMonitor();
  render();
  requestAnimationFrame(animate);
}

function main() {
  init();
  animate();
}